package org.tcdb.biotools.util;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import org.biojava3.core.sequence.ProteinSequence;
import org.biojava3.core.sequence.io.FastaReaderHelper;

public class SequenceRetrieval {

	/**
	 * Returns the first sequence from a query to TCDB using an accession number. To ensure that no potential 
	 * matches were ignored, either use a five-digit TCID or use the getSequencesForTcid() method, which
	 * returns a linked hash map of results.
	 * @param TCID
	 * @return a ProteinSequence
	 * @throws Exception
	 */
	public static ProteinSequence getSequenceForTcid(String TCID) throws Exception {
		InputStream tcConnection = openTcdbConnection("tcid", TCID);
		LinkedHashMap<String, ProteinSequence> sequences = FastaReaderHelper.readFastaProteinSequence(tcConnection);
		Set<String> keys = sequences.keySet();
		List<ProteinSequence> entries = new ArrayList<ProteinSequence>();
		for (String key : keys) {
			entries.add(sequences.get(key));
		}
		tcConnection.close();
		return entries.get(0);
	}
	
	/**
	 * Returns a linked hash map of sequences with accession numbers as keys from a query to TCDB using any valid
	 * length of TCID (1 < 5).
	 * @param TCID
	 * @return linked hash map keyed by accession number
	 * @throws Exception
	 */
	public static LinkedHashMap<String, ProteinSequence> getSequencesForTcid(String TCID) throws Exception {
		InputStream tcConnection = openTcdbConnection("tcid", TCID);
		LinkedHashMap<String, ProteinSequence> sequences = FastaReaderHelper.readFastaProteinSequence(tcConnection);
		tcConnection.close();
		return sequences;
	}
	
	/**
	 * Returns the ProteinSequence for a specific accession number from TCDB's database.
	 * @param accession number
	 * @return a ProteinSequence
	 * @throws Exception
	 */
	public static ProteinSequence getSequenceForTcAccession(String acc) throws Exception {
		InputStream tcConnection = openTcdbConnection("acc", acc);
		ProteinSequence sequence = FastaReaderHelper.readFastaProteinSequence(tcConnection).get(acc);
		tcConnection.close();
		return sequence;
	}
	
	/**
	 * Opens a new connection to TCDB and returns the input stream.
	 * @param api
	 * @param query
	 * @return
	 * @throws IOException
	 */
	private static InputStream openTcdbConnection(String api, String query) throws IOException {
		if (api.equalsIgnoreCase("acc")){
			URL tcdbURL = new URL(String.format("http://www.tcdb.org/api.php?acc=%s", query));
			return tcdbURL.openStream();
		} else if (api.equalsIgnoreCase("tcid")) {
			URL tcdbURL = new URL(String.format("http://www.tcdb.org/api.php?tcid=%s", query));
			return tcdbURL.openStream();
		} else {
			throw new IOException("Unsupported API selection- should be 'acc' or 'tcid'.");
		}
	}
	
}
